﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;

namespace LeafHttp.PostTool
{
    public partial class Form1 : Form
    {
        private RequestConfig _requestConfig;
        private Thread _requestThread;
        private int _iterations;
        private int _interval;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            txtIterations.Text = "1";
            txtInterval.Text = "1";
            WriteOutput("在浏览器中按‘F12’打开‘开发人员工具’，切换到‘网络’页监控网页请求；");
            WriteOutput("待请求出现后，在请求上点击右键，选择‘复制’-‘以cURL（bash）格式复制’；");
            WriteOutput("粘贴到命令文本框中，点击‘解析命令’，然后点击‘开始执行’发送请求。");
            txtCommand.Focus();
        }

        private void WriteOutput(string text)
        {
            txtOutput.AppendText(text + Environment.NewLine);
        }

        private string LimitString(string text, int maxLen)
        {
            if (text.Length > maxLen)
            {
                return text.Substring(0, maxLen / 2) + "..." + text.Substring(text.Length - maxLen / 2 - 1);
            }
            return text;
        }

        private void btnParseCmd_Click(object sender, EventArgs e)
        {
            if (txtCommand.Text.Trim() == string.Empty)
            {
                MessageBox.Show("请输入CURL脚本！");
                return;
            }

            txtRequest.Clear();
            txtResponse.Clear();
            _requestConfig = new CurlParser().CurlToRequestConfig(txtCommand.Text);
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("Url: ");
            sb.AppendLine("  " + _requestConfig.Url);
            sb.AppendLine();
            sb.AppendLine("Headers: ");
            if (_requestConfig.Headers.Count > 0)
            {
                foreach (var item in _requestConfig.Headers)
                {
                    sb.AppendLine($"  {item.Key}: {item.Value}");
                }
            }
            else
            {
                sb.AppendLine("  无");
            }
            sb.AppendLine();
            sb.AppendLine("Cookies: ");
            if (_requestConfig.Cookies.Count > 0)
            {
                foreach (var item in _requestConfig.Cookies)
                {
                    sb.AppendLine($"  {item.Name}: {item.Value}");
                }
            }
            else
            {
                sb.AppendLine("  无");
            }
            sb.AppendLine();
            sb.AppendLine("Body: ");
            sb.AppendLine("  " + (_requestConfig.Data != null ? _requestConfig.Data.ToString() : "  无"));
            txtRequest.AppendText(sb.ToString());
            tabControl1.SelectedIndex = 1;
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            if (btnRun.Text == "开始执行")
            {
                if (_requestConfig == null || string.IsNullOrEmpty(_requestConfig.Url))
                {
                    MessageBox.Show("请先解析命令！");
                    return;
                }

                if (txtIterations.Text.Trim() == string.Empty)
                {
                    txtInterval.Text = "1";
                }
                
                if (!int.TryParse(txtIterations.Text.Trim(), out _iterations))
                {
                    MessageBox.Show("请正确输入‘迭代次数’！");
                    return;
                }

                if (txtInterval.Text.Trim() == string.Empty)
                {
                    txtInterval.Text = "1";
                }
                
                if (!int.TryParse(txtInterval.Text.Trim(), out _interval))
                {
                    MessageBox.Show("请正确输入‘间隔时间’！");
                    return;
                }

                _requestThread = new Thread(RequestThread);
                _requestThread.IsBackground = true;
                _requestThread.Start();
                txtIterations.Enabled = false;
                txtInterval.Enabled = false;
                btnRun.Text = "停止执行";
                btnRun.BackColor = Color.Red;
                tabControl1.SelectedIndex = 2;
            }
            else
            {
                _requestThread.Abort();
                txtIterations.Enabled = true;
                txtInterval.Enabled = true;
                btnRun.Text = "开始执行";
                btnRun.BackColor = this.BackColor;
                WriteOutput("停止执行请求");
            }
        }

        private void RequestThread()
        {
            int iter = 0;
            HttpClient httpClient = new HttpClient();
            while (iter < _iterations)
            {
                var result = httpClient.Request(_requestConfig).Execute();
                iter++;
                Invoke(new MethodInvoker(delegate
                {
                    txtResponse.Clear();
                    txtResponse.AppendText(Convert.ToString(result.IsSuccess ? result.Response.Data : result.Message));
                    if (result.IsSuccess)
                    {
                        WriteOutput($"{iter}.请求{LimitString(_requestConfig.Url, 25)}成功，返回数据：{LimitString(Regex.Unescape(Convert.ToString(result.Response.Data)), 40)}");
                    }
                    else
                    {
                        WriteOutput($"{iter}.请求{LimitString(_requestConfig.Url, 25)}出错，错误信息：{LimitString(Regex.Unescape(result.Message), 40)}");
                    }
                }));
                Thread.Sleep(_interval * 1000);
            }

            this.Invoke(new MethodInvoker(delegate
            {
                WriteOutput("请求执行完成");
                txtIterations.Enabled = true;
                txtInterval.Enabled = true;
                btnRun.Text = "开始执行";
                btnRun.BackColor = this.BackColor;
                if (_iterations > 1)
                {
                    MessageBox.Show("执行完毕");
                }
            }));
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtCommand.Clear();
            txtRequest.Clear();
            txtResponse.Clear();
            txtOutput.Clear();
        }
    }
}
